package com.library.service.impl;

import com.library.dao.BookDao;
import com.library.dao.BorrowRecordDao;
import com.library.dao.ReaderDao;
import com.library.entity.Book;
import com.library.entity.BorrowRecord;
import com.library.entity.Reader;
import com.library.service.BorrowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class BorrowServiceImpl implements BorrowService {

    @Autowired
    private BorrowRecordDao borrowRecordDao;

    @Autowired
    private BookDao bookDao;

    @Autowired
    private ReaderDao readerDao;

    @Override
    @Transactional
    public boolean borrowBook(Integer readerId, Integer bookId) {
        Reader reader = readerDao.findById(readerId);
        Book book = bookDao.findById(bookId);
        
        if (reader == null || book == null) {
            return false;
        }
        
        // 检查读者状态
        if (reader.getStatus() != 1) {
            return false;
        }
        
        // 检查图书可借数量
        if (book.getAvailableQuantity() <= 0) {
            return false;
        }
        
        // 检查读者当前借阅数量
        List<BorrowRecord> borrowingRecords = borrowRecordDao.findBorrowingRecords();
        long currentBorrowCount = borrowingRecords.stream()
                .filter(record -> record.getReaderId().equals(readerId))
                .count();
        
        if (currentBorrowCount >= reader.getMaxBooks()) {
            return false;
        }
        
        // 创建借阅记录
        BorrowRecord record = new BorrowRecord();
        record.setReaderId(readerId);
        record.setBookId(bookId);
        record.setBorrowDate(new Date());
        
        // 设置还书日期（30天后）
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, 30);
        record.setDueDate(calendar.getTime());
        
        // 减少图书可借数量
        if (bookDao.updateAvailableQuantity(bookId, -1) > 0) {
            return borrowRecordDao.insert(record) > 0;
        }
        
        return false;
    }

    @Override
    @Transactional
    public boolean returnBook(Integer recordId) {
        BorrowRecord record = borrowRecordDao.findById(recordId);
        if (record == null || record.getStatus() != 0) {
            return false;
        }
        
        // 更新借阅记录状态
        record.setReturnDate(new Date());
        record.setStatus(1);
        
        // 增加图书可借数量
        if (borrowRecordDao.updateReturn(recordId, new Date(), 1) > 0) {
            return bookDao.updateAvailableQuantity(record.getBookId(), 1) > 0;
        }
        
        return false;
    }

    @Override
    @Transactional
    public boolean renewBook(Integer recordId) {
        BorrowRecord record = borrowRecordDao.findById(recordId);
        if (record == null || record.getStatus() != 0) {
            return false;
        }
        
        // 检查续借次数
        if (record.getRenewCount() >= 2) {
            return false;
        }
        
        // 检查是否已逾期
        if (new Date().after(record.getDueDate())) {
            return false;
        }
        
        // 延长还书日期（15天）
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(record.getDueDate());
        calendar.add(Calendar.DAY_OF_MONTH, 15);
        
        return borrowRecordDao.renew(recordId, calendar.getTime(), record.getRenewCount() + 1) > 0;
    }

    @Override
    public List<BorrowRecord> getReaderBorrowRecords(Integer readerId) {
        return borrowRecordDao.findByReaderId(readerId);
    }

    @Override
    public List<BorrowRecord> getAllBorrowRecords() {
        return borrowRecordDao.findAll();
    }

    @Override
    public List<BorrowRecord> getBorrowingRecords() {
        return borrowRecordDao.findBorrowingRecords();
    }

    @Override
    public List<BorrowRecord> getOverdueRecords() {
        return borrowRecordDao.findOverdueRecords(new Date());
    }
}